%% @doc The opponents module keeps track of all players stats, eg victory points and development cards. 
%% @end
-module(opponents).
-export([init/0,opponents/2]).


%% @doc Starts opponents/2 a new process
%% @spec init() -> Pid
%% @end
init() -> 
	%{PlayerNr, VPoints, Devcards, Knights, Roads, Largest army, Longest road}
	spawn(fun() -> opponents([{0,0,0,0,0,false,false},{1,0,0,0,0,false,false},{2,0,0,0,0,false,false},{3,0,0,0,0,false,false}],[] ) end).

%% @doc The main function of the module. Keeps track of all players victory points, development cards, played knights and if some one has the largest army and/or the longest road. When the bot places a robber this function decides from who to take a resource from.
%% @end
opponents(Opp,IDs) -> 
    receive 
        {initIDs,NewIDs} -> 
            opponents(Opp, NewIDs);
		{add_VPoints, Value, PlayerNr} -> %Add Value victory points to PlayerNr
			{A,B,C,D,E,F,G} = lists:keyfind(PlayerNr,1,Opp),
			opponents(lists:keyreplace(PlayerNr,1,Opp,{A,B+Value,C,D,E,F,G}),IDs);
		{add_Card,    PlayerNr} -> %Add a dev card to PlayerNr
			{A,B,C,D,E,F,G} = lists:keyfind(PlayerNr,1,Opp),
			opponents(lists:keyreplace(PlayerNr,1,Opp,{A,B,C+1,D,E,F,G}),IDs);
		{remove_Card, PlayerNr} -> %Add remove a dev card from PlayerNr
			{A,B,C,D,E,F,G} = lists:keyfind(PlayerNr,1,Opp),
			opponents(lists:keyreplace(PlayerNr,1,Opp,{A,B,C-1,D,E,F,G}),IDs);
		{add_Knight , PlayerNr} -> %Add a knight to PlayerNr
			{A,B,C,D,E,F,G} = lists:keyfind(PlayerNr,1,Opp),
			opponents(lists:keyreplace(PlayerNr,1,Opp,{A,B,C,D+1,E,F,G}),IDs);
		{add_Road   , PlayerNr} -> %Add a road to PlayerNr
			{A,B,C,D,E,F,G} = lists:keyfind(PlayerNr,1,Opp),
			opponents(lists:keyreplace(PlayerNr,1,Opp,{A,B,C,D,E+1,F,G}),IDs);
        {set_LA, PN} ->
            {A,B,C,D,E,F,G} = lists:keyfind(PN,1,Opp),
            NOpp = lists:map(fun({A,B,C,D,E,F,G}) -> if F == true -> io:fwrite("Opponents: Player~w lost la and ~w got it~n",[A,PN]),{A,B-2,C,D,E,false,G}; true -> {A,B,C,D,E,false,G} end end,Opp),
            opponents(lists:keyreplace(PN,1,NOpp,{A,B+2,C,D,E,true,G}),IDs);
        {set_LR, PN} ->
            {A,B,C,D,E,F,G} = lists:keyfind(PN,1,Opp),
            NOpp = lists:map(fun({A,B,C,D,E,F,G}) -> if G == true -> io:fwrite("Opponents: Player~w lost la and ~w got it~n",[A,PN]),{A,B-2,C,D,E,F,false}; true -> {A,B,C,D,E,F,false} end end,Opp),
            opponents(lists:keyreplace(PN,1,NOpp,{A,B+2,C,D,E,F,true}),IDs);
		{diff_Knights, PID, Knights} -> %sends the difference of knights between the bot and the max(opponent)
			O = lists:max(lists:map(fun({_,_,_,D,_,_,_}) -> D end, Opp)),
			PID ! (O-Knights),
			opponents(Opp,IDs);
		{diff_Roads, PID, Roads  } -> %sends the difference of roads between the bot and the max(opponent)
			O = lists:max(lists:map(fun({_,_,_,_,E,_,_}) -> E end, Opp)),
			PID ! (O-Roads),
			opponents(Opp,IDs);
        {chooseVictim, M} -> %%%%%Viktigt: kolla så den man tar från har resurs, behöver ändra endel för det
			VL     = createVictimList(tl(M),tl(Opp)), %tl because of our bot is the head of M
			if
				length(VL) > 1 ->
					{PN,_} = lists:foldl(fun({PN1,VP1},{PN2,VP2}) -> if VP1>VP2 -> {PN1,VP1}; true -> {PN2,VP2} end end,{-1,-1},VL);
            	true           ->
					{PN,_} = VL
			end,
			{parse_message,PMPid} = lists:keyfind(parse_message,1,IDs),
			PMPid!{chooseplayer,PN},
			opponents(Opp,IDs);
		{getPlayersVP,Pid} -> Pid ! {playersVP,allPlayersVP(0,Opp,[])},
							opponents(Opp,IDs);
		{getPlayersRoads,Pid} -> Pid ! {playerRoads,allPlayersRoads(0,Opp,[])},
								opponents(Opp,IDs);
		{getPlayerLargestArmy,Pn,Pid} -> {_,_,_,_,_,F,_} = lists:keyfind(Pn,1,Opp),
										 Pid ! {playerLA,F},
										 opponents(Opp,IDs);
		{getPlayerWithLR,Pid} -> Pid ! {playerWithLR,playerWithLR(0,Opp)},
											opponents(Opp,IDs);
		{getPlayersKnights,Pid} -> Pid ! {playersKnights,allPlayersKnights(0,Opp,[])},
									opponents(Opp,IDs);
		{getPlayerVP,Pn,Pid} -> {_,B,_,_,_,_,_} = lists:keyfind(Pn,1,Opp),
								Pid ! {playerVP,B},
								opponents(Opp,IDs)
    end.

createVictimList([],[]) -> [];
createVictimList(["true"|VL],[{PN,VP,_,_,_,_,_}|OL]) ->
	[{PN,VP}] ++ createVictimList(VL,OL);
createVictimList([_|VL],[_|OL]) ->
	createVictimList(VL,OL).

allPlayersVP(4,_,VP) -> lists:reverse(VP);
allPlayersVP(Count,Opp,VP) -> {_,B,_,_,_,_,_} = lists:keyfind(Count,1,Opp),
						   allPlayersVP(Count+1,Opp,[B|VP]).

playerWithLR(4,_) -> -1;
playerWithLR(Count,Opp) -> {_,_,_,_,_,_,G} = lists:keyfind(Count,1,Opp),
						   case G of
								true -> Count;
								false -> playerWithLR(Count+1,Opp)
						   end.

allPlayersRoads(4,_,Roads) -> lists:reverse(Roads);
allPlayersRoads(Count,Opp,Roads) -> {_,_,_,_,E,_,_} = lists:keyfind(Count,1,Opp),
							  allPlayersRoads(Count+1,Opp,[E|Roads]).
							  
allPlayersKnights(4,_,Roads) -> lists:reverse(Roads);
allPlayersKnights(Count,Opp,Knights) -> {_,_,_,D,_,_,_} = lists:keyfind(Count,1,Opp),
							  allPlayersKnights(Count+1,Opp,[D|Knights]).							  
